﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IdentityModel.Selectors;
using System.ServiceModel;
using ICeFramework.Common.Configuration;
using ICeFramework.Common.DataLayer;
using ICeFramework.Common.DataLayer.Enums;
using ICeFramework.Common.DataLayer.Exceptions;
using ICeFramework.Common.DataLayer.Interfaces;
using ICeFramework.Serialization;
using ICeFramework.DataAccess.DataLayer.MsSQL;

namespace ICeFramework.DataAccess.Remote
{
    public class RemoteDataAccess : IRemoteDataAccess
    {
        IDataAccessService _dataAccessService;
        public IDataAccessService DataAccessService
        {
            get 
            {
                if (_dataAccessService == null)
                {
                    UserAuth();
                    switch (ConfigurationHelper.GetServerType())
                    {
                        case ServerType.MsSql:
                            _dataAccessService = new MsSQLDataAccessService();
                            break;
                        case ServerType.MySql:
                            throw new NotImplementedException();
                            break;
                        case ServerType.Remote:
                            string url = ConfigurationHelper.GetRemoteUrl(string.Empty);
                            if (string.IsNullOrEmpty(url))
                            {
                                throw new DataAccessException("The remote url is empty !");
                            }
                            _dataAccessService = new MsSQLDataAccessService(new Uri(url), ConfigurationHelper.GetRemoteUserName(string.Empty), ConfigurationHelper.GetRemotePassword(string.Empty));
                            break;
                        default:
                            throw new DataAccessException("There are no connections (local or remote) properly defined.");
                    }
                }
                return _dataAccessService; 
            }
        }

        #region IRemoteDataAccess Members

        public string ParamToken
        {
            get { return ConfigurationHelper.GetServerType() == ServerType.MsSql ? "@" : ""; }
        }

        public DataTable Fill(DataTable table, EntityFilter filter, EntityOrder order, IDbTransaction transaction)
        {
            DataAccessService.Fill(table, filter, order, transaction);
            return table;
        }

        void _adapter_FillError(object sender, FillErrorEventArgs e)
        {
        }

        public DataTable Fill(DataTable table, EntityFilter filter, EntityOrder order, int pageIndex, int pageSize, out long totalRowsCount, IDbTransaction transaction)
        {
            DataAccessService.Fill(table, filter, order, pageIndex, pageSize, out totalRowsCount, transaction);
            return table;
        }

        public DataTable Fill(DataTable table, StoredProcedureDefinition spDefinition, EntityOrder order, IDbTransaction transaction)
        {
            DataAccessService.Fill(table, spDefinition, order, transaction);
            return table;
        }

        public int Count(DataTable table, EntityFilter filter)
        {
            return DataAccessService.Count(table, filter);
        }

        public DataTable Update(DataTable table, byte[] rowArray, byte[] columnArray, IDbTransaction transaction)
        {
            DataRow row = null;
            if (rowArray != null)
            {
                row = (DataRow)BinarySerialization.Deserialize(rowArray);
            }
            List<EntityColumn> columns = (List<EntityColumn>)BinarySerialization.Deserialize(columnArray);
            if (row == null)
            {
                DataAccessService.Update(row, columns, transaction);
                return row.Table;
            }
            else
            {
                DataAccessService.Update(table, columns, transaction);
                return table;
            }
        }

        #endregion

        private void UserAuth()
        {
            string a = ServiceSecurityContext.Current.WindowsIdentity.Name;
        }

        public class UserAuthentication : UserNamePasswordValidator
        {
            // This method validates users. It allows in two users, test1 and test2 
            // with passwords 1tset and 2tset respectively.
            // This code is for illustration purposes only and 
            // MUST NOT be used in a production environment because it is NOT secure.	
            public override void Validate(string userName, string password)
            {
                if (string.IsNullOrEmpty(userName))
                {
                    throw new ArgumentNullException("userName", "userName must not be null or empty.");
                }

                if (string.IsNullOrEmpty(password))
                {
                    throw new ArgumentNullException("password", "password must not be null or empty.");
                }

                if (userName != ICeFramework.Utilities.Security.Hash.GetMd5Hash("pass1") || password != ICeFramework.Utilities.Security.Hash.GetMd5Hash("pass2"))
                {
                    throw new FaultException("Unknown Username or Incorrect Password");
                }
            }

            
        }

    }
}
